/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Exercicio2;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Pedro
 * O arquivo lido deve conter a seguinte estrutura:
 * sendo A elementros da matriz 1 e B elementos da matriz 2 devem estar separados por "|":
 * 1
 * A¹¹|A¹²|A¹³
 * A²¹|A²²|A²³
 * A³¹|A³²|A³³
 *
 *
 * B¹¹|B¹²|B¹³
 * B²¹|B²²|B²³
 * B³¹|B³²|B³³
 *
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws FileNotFoundException, IOException {
        // TODO code application logic here
        FileReader reader = new FileReader(args[0]); //Cria arquivo para leitura
        BufferedReader leitor = new BufferedReader(reader); //Cria buffer de leitura
        String lido; //Auxiliar
        int[][] matriz1 = null; //matriz 1 m1xn1 onde m1==n1
        int[][] matriz2 = null; //matriz 2 m2xn2 onde m2==n2
        int[][] matrizResultado = null; //matriz resultado m1xn2 onde consequentemente m1==n2
        int tamMatriz = 0; //controle do tamanho da matriz
        int linha = 0; //controle da linha lida no arquivo
        int qualMatriz = 1;//controle de qual matriz esta sendo lida
        int cols2 = 0;//numero de colunas de b
        final int P = 4;
        ThreadMultiplica[] thread;

        /**
         * Este bloco monta as matrizes de acordo com as linhas do arquivo
         */
        tamMatriz = Integer.parseInt(leitor.readLine());

        matriz1 = new int[tamMatriz][];
        for (int i = 0; i < tamMatriz; i++) {
            matriz1[i] = new int[tamMatriz];
        }

        matriz2 = new int[tamMatriz][];
        for (int i = 0; i < tamMatriz; i++) {
            matriz2[i] = new int[tamMatriz];
        }

        matrizResultado = new int[tamMatriz][];
        for (int i = 0; i < tamMatriz; i++) {
            matrizResultado[i] = new int[tamMatriz];
        }
            while (leitor.ready()) {
                linha++;

                lido = leitor.readLine();

                if (lido.trim().equalsIgnoreCase("")) {
                    qualMatriz = 2;
                    linha = 0;
                    continue;
                }

                String[] numeros = lido.split("\\|");

                if (qualMatriz == 1) {

                    for (int i = 0; i < numeros.length; i++) {
                        matriz1[linha - 1][i] = Integer.parseInt(numeros[i]);
                    }


                } else {

                    for (int i = 0; i < numeros.length; i++) {
                        matriz2[linha - 1][i] = Integer.parseInt(numeros[i]);
                    }

                }
        }

        thread = new ThreadMultiplica[P];

        //Inicia a execução de cada thread
        for (int i = 0; i < P; i++) {
            thread[i] = new ThreadMultiplica(tamMatriz);
            thread[i].start();
        }

        
         int line1, line2, column1, column2;
         
         line1 = line2 = column1 = column2 = 0;
         
         boolean isFinal = false;
         int contP = 0;
         while (!isFinal)
         {
             for(int i = 0; i < tamMatriz; i++)
             {
               thread[contP%P].getChannelParametros().send(matriz1[line1][i]);
             }

             for(int j = 0; j < tamMatriz; j++)
             {
                 thread[contP%P].getChannelParametros().send(matriz2[j][column1]);
             }

             matrizResultado[line1][column1] = thread[contP%P].getChannelResposta().receive();

             if(line1==tamMatriz - 1 && column1==tamMatriz - 1)
             {isFinal = true;}

             if (column1==tamMatriz - 1)
             { column1 = 0; line1++;}else{
             
             column1++;}
             contP++;

         }
           
        //imprime a matriz resutado
        GravaARquivoResultado(matrizResultado);
        ImprimeMatriz(matrizResultado);
    }

    //metodo helper que imprime a matriz na tela
    public static void ImprimeMatriz(int[][] matriz) {
        for (int[] inteiro : matriz) {
            for (int i : inteiro) {
                System.out.print(i + " ");
            }
            System.out.println("");
        }
    }

        public static void GravaARquivoResultado(int[][] matriz) {

            File texto = new File("C:\\arquivoResultado.txt");
            FileWriter escritor = null;

        try {
             escritor = new FileWriter(texto);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        BufferedWriter buffer = new BufferedWriter(escritor);

          for (int[] inteiro : matriz) {
            for (int i : inteiro) {
                try {
                    buffer.write(i + "|");
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
                
           
            }
            try {
                buffer.newLine();
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
        try {
            buffer.flush();
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}
